iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 19
3
Modern Web

React 30天系列 第 19

Day 19-你好,React Router 4(安裝及角色介紹)

  • 分享至 

  • xImage
  •  

前情提要:昨天大致總結了一下Redux,今天來看看React Router吧!

React Router是React的路由解决方案,它可以讓UI可以與URL同步。
這邊使用的是react router 4,前面幾版就讓它留在歷史的洪流吧!
如果看到這篇時已經有React Router 5,6,7,也讓這篇成為歷史的塵埃吧。
欸一開頭就這麼沈重接下來怎麼走下去XD

當打開react-router的網站後會看到幾個選項,web/native/core,接下來針對web這部分來學習react-router

那我們先直接安裝react-router-dom吧!

yarn add react-router-dom

在react-router這部分沒有太多的概念描述,大多為用法操作,就讓我們先稍微看一下react router的效果吧~
首先看看官網提供的範例:
安裝完react-router-dom後:

  1. 匯入BrowserRouter、Route和Link,並將BrowserRouter重新命名為Router
  2. 建立三個簡單的component,分別為Index、About和Users
  3. 使用<Router/>處理這三“頁”的component

※特別注意:在react router如果要連到其他頁面我們不使用<a href="/">,使用<Link to="/">來替代

import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

const Index = () => <h2>Home</h2>;
const About = () => <h2>About</h2>;
const Users = () => <h2>Users</h2>;

const AppRouter = () => (
  <Router>
    <div>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about/">About</Link>
          </li>
          <li>
            <Link to="/users/">Users</Link>
          </li>
        </ul>
      </nav>

      <Route path="/" exact component={Index} />
      <Route path="/about/" component={About} />
      <Route path="/users/" component={Users} />
    </div>
  </Router>
);

export default AppRouter;

執行畫面如下:
https://i.imgur.com/FZ21xlg.gif

有了大雛形後接下來來看小細節吧!
React Router中有三種component,分別有:router components、route matching components和navigation components。
而剛剛提到的所有component都是由react-router-dom匯入使用。

router components- <Routers>

router components是react router的核心。在web專案,react-router-dom提供兩種不同的routers,分別為:<BrowserRouter><HashRouter>,這兩個routers都能為我們建立特定的history object。一般來說,如果有server回應request,則使用<BrowserRouter>;如果使用靜態文件server,則使用<HashRouter>
基本用法:

import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  holder
);

更多設定可參考Router api

route matching components- <Route> 和 <Switch>

路由匹配是透過比較<Route/>的path prop和當時的location pathname來做比對
比如說目前的location pathname為about
https://ithelp.ithome.com.tw/upload/images/20181026/20111595ZTA6e17IbB.png
那我在Route的path設定path="/about/"就能夠匹配到對應的about,使用對應的component渲染頁面內容。

<Route path="/about/" component={About} />

當什麼都匹配不到時則回傳null,如果在Route component沒有設定任何path的話則永遠都會被匹配。
另外在<Switch/>則用於組合<Route/>,使用方式如下:

<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route path="/contact" component={Contact} />
  {/* 當上方的path都沒有被匹配到 <NoMatch> 就會被渲染 */}
  <Route component={NoMatch} />
</Switch>

<Switch/>雖然不一定要用它,但它很有用。
<Switch>遍歷它所有的子層<Route>,然後只渲染與它當前location匹配的第一個<Route/>。這在當我們有多個route path匹配同個pathname時,或者在route間使用動畫轉場,或是判斷當前location沒有匹配的route時會很有幫助。

渲染route的方法除了設定component外還有render和children。詳情可參考Route api文件

一般來說,除非有額外的內部變數需要傳入function處理,不然通常使用component設定就可以了。而且我們不該在component prop傳入內部變數,因為這樣會產生不需要的component卸載和重新掛載。

const Home = () => <div>Home</div>;

const App = () => {
  const someVariable = true;

  return (
    <Switch>
      {/* 好的做法 */}
      <Route exact path="/" component={Home} />
      <Route
        path="/about"
        render={props => <About {...props} extra={someVariable} />}
      />
      {/* 不要這麼做 */}
      <Route
        path="/contact"
        component={props => <Contact {...props} extra={someVariable} />}
      />
    </Switch>
  );
};

navigation components- <Link>、<NavLink>和<Redirect>

<Link> component在application內部創建了一個link,無論在哪邊渲染<Link>,它都會被渲染成html的anchor(<a>)

<Link to="/">Home</Link>
// <a href='/'>Home</a>

<NavLink>是特殊類型的<Link>,當anchor被點擊的時候可以設定"active" class name

// location = { pathname: '/react' }
<NavLink to="/react" activeClassName="hurray">
  React
</NavLink>
// <a href='/react' className='hurray'>React</a>

任何時間當我們想強制navigation時,可以渲染<Redirect>,當<Redirect>被渲染時會根據"to"的設定前往指定路徑。

// <a href='/react' className='hurray'>React</a>
<Redirect to="/login" />

今天大致上把react router常用的component都角色介紹完了,明天再來實際操作使用吧!


上一篇
Day 18-回顧Redux
下一篇
Day 20-使用react-router繼續擴增todos吧( ´▽` )ノ
系列文
React 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言